#pragma once
#include <functional>
#include <memory>
#include <nice2d/predef.h>
#include <nice2d/component.h>

class State
{
public:
    State() = delete;
    State(const std::string& name);
    virtual ~State();
public:
    std::string getStateName()const;

    bool isRunning()const;
    void enter();
    void exit();

    virtual void update(float deltaTime);
protected:
    virtual void onEnter();
    virtual void onExit();
private:
    std::unique_ptr<class StateData> data;
};

class StateMachine : public Component
{
    DECLARE_OBJECT(StateMachine)
public:
    StateMachine();
    ~StateMachine();
public:
    void setInitialState(std::shared_ptr<State> state);
    void addTransition(std::shared_ptr<State> src,std::shared_ptr<State> dst,std::function<bool()> functor);
    void switchState(const std::string& src,const std::string& dst,std::function<bool()> functor);

    bool start();
    bool isRunning()const;
    void stop();
    std::shared_ptr<State> getRunningState();

    void update(float deltaTime)override;
private:
    std::unique_ptr<class StateMachineData> data;
};
